﻿if (!window.slideo)
	slideo = {};

// Load constants
var MODES = new Array();
MODES["PICK"] = 1;
MODES["USER"] = 2;
MODES["REMV"] = 3;
MODES["SAVE"] = 4;
MODES["PATH"] = 5;
MODES["ANIM"] = 6;
MODES["TIME"] = 7;
MODES["HIDE"] = 8;
var SUBMODES = new Array();
SUBMODES["USER_INIT"] = 5;
SUBMODES["USER_SELECTED"] = 6;
SUBMODES["USER_MOVING"] = 7;
SUBMODES["USER_MOVED"] = 8;
SUBMODES["USER_CANCELED"] = 9;

SUBMODES["PATH_INIT"] = 10;
SUBMODES["PATH_SELECTED"] = 11;
SUBMODES["PATH_DONE"] = 12;

/*
 * Initial position of the user which is operated.
 */
var initX = 0;
var initY = 0;

/*
 * Objects that are being moved.
 */
var objMoving = null;

/*
 * Paths designed by users.
 * Key: path name; Value: point collection in string (For example 100,100 200,200 300,300).
 *
 * PUs:
 * Key: path name; Value: user name.
 *
 * PPs:
 * Key: path name; Value: point objects.
 *
 * PTs:
 * Key: path name; Value: time collection each of which is elapsed in each path section.
 *
 * UinF: all the user objects in the field
 * 
 * UStats:
 * Key: user name; Value: user status;
 */
var Paths = new Array();
var PPs = new Array();
var PUs = new Array();
var PTs = new Array();
var UinF = new Array();
var UStats = new Array();
var pathIdx = 0;
var spotIdx = 0;
var startPos = null;
var colors = new Array("#FF063DB5", "#FFD10FEA", "#FFDABF08", "#FFDA2308", "#FF10F4D2", "#FF571522");
var clrIdx = 0;
var iv = true; // path status;
/*
 * Animations
 * Value: animation's name
 */
var Stories = new Array();

var Plugin = null;

var cnt = 0;
var bDdrop = false;
var bTimeMoving = false;
var bSpotMoving = false;
var bUserMoving = false;
var bTsMoving = false;
var bClockMoving = false;
var bPinning = false;
var tsCurPos = null;
var tsCurAng = null;
var bUBInit = false;
var PinSet = new Object(); // Name as property whose value is set to 1 for placement.
var mode = MODES["PICK"]; // Init Mode
var pathnamesel = null;
var submode = -1; // No sub-mode initially

/*
 * Time configuration
 */
var timeUnit = 1; // 1 second.

/*
 * Mode controllers
 */
var cmpPick = null;
var cmpUser = null;
var cmpRemv = null;
var cmpSave = null;
var cmpPath = null;
var cmpAnim = null;
var cmpTime = null;
var cmpHide = null;

/*
 * Global references to the canvas.
 */
var editor = null;
var field = null;
var users = null;

function GetPlugin() {
	if (Plugin == null) Plugin = document.getElementById("SilverlightControl");
	return Plugin;
}

function CompSelected(comp) {
	//var Plugin = comp.getHost();
	GetPlugin();
		
	if (cmpPick == null)
		cmpPick = Plugin.content.findName("pick");
	if (cmpUser == null)
		cmpUser = Plugin.content.findName("user");
	if (cmpRemv == null)
		cmpRemv = Plugin.content.findName("remove");
	if (cmpSave == null)
		cmpSave = Plugin.content.findName("save");
	if (cmpPath == null)
		cmpPath = Plugin.content.findName("path");
	if (cmpAnim == null)
		cmpAnim = Plugin.content.findName("animate");
	if (cmpTime == null)
		cmpTime = Plugin.content.findName("time");
	if (cmpHide == null)
		cmpHide = Plugin.content.findName("hidePath");
	cmpPick.children.getItem(0)["StrokeThickness"] = 1;
	cmpUser.children.getItem(0)["StrokeThickness"] = 1;
	cmpRemv.children.getItem(0)["StrokeThickness"] = 1;
	cmpSave.children.getItem(0)["StrokeThickness"] = 1;
	cmpPath.children.getItem(0)["StrokeThickness"] = 1;
	cmpAnim.children.getItem(0)["StrokeThickness"] = 1;
	cmpTime.children.getItem(0)["StrokeThickness"] = 1;
	cmpHide.children.getItem(0)["StrokeThickness"] = 1;
	comp.children.getItem(0)["StrokeThickness"] = 2;
	
	var name = comp["Name"];
	if (name == cmpUser["Name"]) {
		Plugin.content.findName("Users")["Visibility"] = "Visible";
		Plugin.content.findName("TEditor")["Visibility"] = "Collapsed";
		
		for ( key in UStats)
			/* Only the one who is not initialized will be set to USER_INIT. */
			//if (UStats[key] == null)
				UStats[key] = SUBMODES["USER_INIT"];
		
		bUB(Plugin);
	} else if (name == cmpAnim["Name"]) {
		Plugin.content.findName("Users")["Visibility"] = "Collapsed";
		Plugin.content.findName("TEditor")["Visibility"] = "Collapsed";
		//buildAnimation(Plugin);
		bA(Plugin);
	} else if (name == cmpPath["Name"]) {
		Plugin.content.findName("Users")["Visibility"] = "Collapsed";
		Plugin.content.findName("TEditor")["Visibility"] = "Collapsed";
		for ( key in UStats) {
			UStats[key] = SUBMODES["PATH_INIT"];
		}
	} else if (name == cmpTime["Name"]){
		Plugin.content.findName("Users")["Visibility"] = "Collapsed";
		Plugin.content.findName("TEditor")["Visibility"] = "Visible";
		if (pathnamesel != null) bTE(Plugin, pathnamesel);
	} else if (name == cmpSave["Name"]){
		Plugin.content.findName("Users")["Visibility"] = "Collapsed";
		Plugin.content.findName("TEditor")["Visibility"] = "Collapsed";
		Commit(Plugin.createObject("downloader"));
	} else if (name == cmpHide["Name"]) {
		sp(!iv);iv = !iv;
	}
	else {
		Plugin.content.findName("Users")["Visibility"] = "Collapsed";
		Plugin.content.findName("TEditor")["Visibility"] = "Collapsed";
	}
}

function UserHasPath(PUs, usrName) {
	//var String = PUs.join(";") + ";";
	
	for (key in PUs) {
		if (usrName == PUs[key])
			return true;
	}
	return false;
	//return (String.indexOf(usrName+";") != -1);
}

function bUB(Plugin) {
	if (!bUBInit) {
		var piero = GetPlayer(Plugin, 'Piero', 10);
		var trez = GetPlayer(Plugin, 'Trezquet', 9);
		var u = Plugin.content.findName("Users");
		
		piero["Canvas.Left"] = 20;
		trez["Canvas.Left"] = 20;
		piero["Canvas.Top"] = 100;
		trez["Canvas.Top"] = 150;
		u.children.add(piero);
		u.children.add(trez);
		
		bUBInit = !bUBInit;
	}
}
function bA(Plugin) {
	var userObj = null;
	
	Stories = new Array();
	for (var pathname in PUs) {
		var idx = pathname.substr(4); // idx to identify the path and its corresponding animation.
		
		var points = Paths[idx];
		//alert(points);
		userObj = Plugin.content.findName(PUs[pathname]);
		
		var width = userObj["Width"];
		var height = userObj["Height"];
		//alert(userObj["Name"]);
		
		var p_array = points.split(" ");
		var len = p_array.length;
		
		var tss = PTs[pathname];
		
		var xaml = userObj["Name"] == "Ball" ? '<Ellipse.Triggers>' : '<Canvas.Triggers>';
		if (userObj["Name"] == "Ball")
	    	xaml += '<EventTrigger RoutedEvent="Ellipse.Loaded">';
	    else
	    	xaml += '<EventTrigger RoutedEvent="Canvas.Loaded">';
	    xaml +=        '<BeginStoryboard>';
	    xaml +=          '<Storyboard x:Name="GoalVideo'+idx+'" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">';

		var f1 = '<DoubleAnimationUsingKeyFrames BeginTime="'+tss[0]+'" ';
	    f1 +=         'Storyboard.TargetName="' + PUs[pathname] + '" ';
	    f1 +=         'Storyboard.TargetProperty="(Canvas.Top)">';
	    
	    var f2 = '<DoubleAnimationUsingKeyFrames BeginTime="'+tss[0]+'" ';
	    f2 +=         'Storyboard.TargetName="' + PUs[pathname] + '" ';
	    f2 +=         'Storyboard.TargetProperty="(Canvas.Left)">';
	    
	    var initX;
	    var initY;
	    
	    for (var i = 0; i < len; i++) {
	    	var xy = p_array[i].split(',');
	    	if (i != 0) {
		    	var x = xy[0] - width/2;
		    	var y = xy[1] - height/2;
		    	var kt = Sec2Hms(Hms2Sec(tss[i])-Hms2Sec(tss[0]));
		    	f1 += '<SplineDoubleKeyFrame KeyTime="'+kt+'" Value="' + y + '"/>';
		    	//f1 += '<SplineDoubleKeyFrame KeyTime="00:00:0' + i + '" Value="' + y + '"/>';
		    	//f1 += '<LinearDoubleKeyFrame  Value="' + xy[1] + '" KeyTime="0:0:' + i + '"/>';
		    	f2 += '<SplineDoubleKeyFrame KeyTime="'+kt+'" Value="' + x + '"/>';
		    	//f2 += '<SplineDoubleKeyFrame KeyTime="00:00:0' + i + '" Value="' + x + '"/>';
		    	//f2 += '<LinearDoubleKeyFrame  Value="' + xy[0] + '" KeyTime="0:0:' + i + '"/>';
	    	} else {
	    		initX = xy[0];
	    		initY = xy[1];
	    	}
	    }
	    
		f1 +=    '</DoubleAnimationUsingKeyFrames>';
		f2 +=    '</DoubleAnimationUsingKeyFrames>';
		
		xaml += f1;
		xaml += f2;
		
		xaml +=          '</Storyboard>';
	    xaml +=        '</BeginStoryboard>';
	    xaml +=      '</EventTrigger>';
	    
	    if (userObj["Name"] == "Ball")
	    	xaml +=    '</Ellipse.Triggers>'; 
	    else
	    	xaml +=    '</Canvas.Triggers>'; 
	    
	    var new_user;
	    if (userObj["Name"] != "Ball") {
	    	new_user = GetPlayer(Plugin, userObj["Name"], gn(userObj), xaml);
	    	//new_user["Canvas.Left"] = userObj["Canvas.Left"];
	    	//new_user["Canvas.Top"] = userObj["Canvas.Top"];
	    	new_user["Canvas.Left"] = initX - new_user["Width"]/2;
	    	new_user["Canvas.Top"] = initY - new_user["Height"]/2;
	    } else {
	    	var userXaml = '<Ellipse Width="8" Height="8" Fill="#FFFFFFFF" Stroke="#FF000000" x:Name="'+userObj["Name"]+'" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  Visibility="Visible" MouseLeftButtonDown="userLeftDown" Canvas.Left="' + (initX-4) + '" Canvas.Top="' + (initY-4) + '">';
	    	userXaml += xaml;
	    	userXaml += "</Ellipse>";
	    	
	    	new_user = Plugin.content.createFromXaml(userXaml);
	    }
		
		field.children.remove(userObj);
		field.children.add(new_user);
		
		Stories.push("GoalVideo"+idx);
	}
	
	//alert(Stories.length);
}

function PinLBD(sender, eventArgs) {
	bPinning = !bPinning;
	GetPlugin();
	if (!bPinning) for (p in PinSet) unpin(p, Plugin);
	var g = sender.findName("g");
	g["Canvas.Top"] = bPinning ? 8 : 13;
}
function pin(name, Plugin) {
	PinSet[name] = 1;
	PinSet[(name+"_anchor")] = 1;
	PinSet[("Ts"+name.substring(6))] = 1;
	Plugin.content.findName(name)["Stroke"]="#FFFFFFFF";
}
function unpin(name, Plugin) {
	if (PinSet[name] != null) {
		delete PinSet[name];
		delete PinSet[(name+"_anchor")];
		delete PinSet[("Ts"+name.substring(6))];
		Plugin.content.findName(name)["Stroke"]="#FF000000";
	}
}
/*
 * build time editor.
 * Example XAML:
 * <Canvas Width="400" Height="40" Canvas.Left="440" Canvas.Top="80" x:Name="TSpots">
		<Path Width="400" Height="1" Fill="#FF063DB5" Stretch="Fill" Stroke="#FF606060" StrokeThickness="1" Data="M0,40 L400,40" Canvas.Top="10" Canvas.Left="0"/>
		<Ellipse Width="20" Height="20" Fill="#FF063DB5" Stroke="#FF000000" StrokeThickness="2" x:Name="TPoint1" MouseLeftButtonDown="TimeUserLeftDown" MouseLeftButtonUp="TimeUserLeftUp" MouseMove="TimeUserMove" Canvas.Left="-10" Canvas.Top="0"/>
		<Ellipse x:Name="TPoint2" Width="20" Height="20" Fill="#FF063DB5" Stroke="#FF000000" StrokeThickness="2" MouseLeftButtonDown="TimeUserLeftDown" MouseLeftButtonUp="TimeUserLeftUp" MouseMove="TimeUserMove" Canvas.Left="30" Canvas.Top="0"/>
		<Ellipse x:Name="TPoint3" Width="20" Height="20" Fill="#FF063DB5" Stroke="#FF000000" StrokeThickness="2" MouseLeftButtonDown="TimeUserLeftDown" MouseLeftButtonUp="TimeUserLeftUp" MouseMove="TimeUserMove" Canvas.Left="70" Canvas.Top="0"/>
		<Ellipse x:Name="TPoint4" Width="20" Height="20" Fill="#FF063DB5" Stroke="#FF000000" StrokeThickness="2" MouseLeftButtonDown="TimeUserLeftDown" MouseLeftButtonUp="TimeUserLeftUp" MouseMove="TimeUserMove" Canvas.Left="110" Canvas.Top="0"/>
		<Ellipse x:Name="TPoint5" Width="20" Height="20" Fill="#FF063DB5" Stroke="#FF000000" StrokeThickness="2" MouseLeftButtonDown="TimeUserLeftDown" MouseLeftButtonUp="TimeUserLeftUp" MouseMove="TimeUserMove" Canvas.Left="150" Canvas.Top="0"/>
		<Path Width="1" Height="120" Fill="#FF063DB5" Stretch="Fill" Stroke="#FF5BE5F9" StrokeThickness="1" Data="M8,40 L8,240" x:Name="TPoint1_anchor" Canvas.Left="0" Canvas.Top="20"/>
		<Path x:Name="TPoint2_anchor" Width="1" Height="120" Fill="#FF063DB5" Stretch="Fill" Stroke="#FF5BE5F9" StrokeThickness="1" Data="M8,40 L8,240" Canvas.Left="40" Canvas.Top="20"/>
		<Path x:Name="TPoint3_anchor" Width="1" Height="120" Fill="#FF063DB5" Stretch="Fill" Stroke="#FF5BE5F9" StrokeThickness="1" Data="M8,40 L8,240" Canvas.Left="80" Canvas.Top="20"/>
		<Path x:Name="TPoint4_anchor" Width="1" Height="120" Fill="#FF063DB5" Stretch="Fill" Stroke="#FF5BE5F9" StrokeThickness="1" Data="M8,40 L8,240" Canvas.Left="120" Canvas.Top="20"/>
		<Path x:Name="TPoint5_anchor" Width="1" Height="120" Fill="#FF063DB5" Stretch="Fill" Stroke="#FF5BE5F9" StrokeThickness="1" Data="M8,40 L8,240" Canvas.Left="160" Canvas.Top="20"/>
			
		<TextBlock Width="60" Height="12" TextWrapping="Wrap" Text="00:00:00" FontSize="8" FontFamily="Lucida Sans Unicode" x:Name="Ts1" Canvas.Left="-20" Canvas.Top="-10"/>
		<TextBlock Width="60" Height="12" FontSize="8" Text="00:00:01" TextWrapping="Wrap" x:Name="Ts2" Canvas.Left="20" Canvas.Top="20"/>
		<TextBlock Width="60" Height="12" FontSize="8" Text="00:00:02" TextWrapping="Wrap" x:Name="Ts3" Canvas.Left="60" Canvas.Top="-10"/>
		<TextBlock Width="60" Height="12" FontSize="8" Text="00:00:03" TextWrapping="Wrap" x:Name="Ts4" Canvas.Left="100" Canvas.Top="20"/>
		<TextBlock Width="60" Height="12" FontSize="8" Text="00:00:04" TextWrapping="Wrap" x:Name="Ts5" Canvas.Left="140" Canvas.Top="-10"/>
		<!-- Hidden Element for storing path name -->
		<TextBlock Width="10" Height="10" Canvas.Left="400" Canvas.Top="0" Text="TextBlock" TextWrapping="Wrap" x:Name="PN" FontSize="8" FontFamily="Arial" Visibility="Collapsed"/>
		
	</Canvas>
 * pn: path name
 * The Point's Naming policy: TPoint<i>.
 * 
 */
 
function bTE(Plugin, pn) {
	var te = Plugin.content.findName("TSpots"); // te: time editor
	//var ta = Plugin.content.findName("TEditor"); // ta: time configuration area
	var slots = Plugin.content.findName("Slots");
	var stubs = Plugin.content.findName("Stubs");
	if (te != null) slots.children.remove(te);
	
	// Build
	var points = PPs[pn];
	var tts = PTs[pn];
	var xaml = '<Canvas Width="400" Height="40" Canvas.Left="0" Canvas.Top="-60" x:Name="TSpots" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">';
	
	var left = -10;
	var ttlWidth = 400;
	var ttlTime = 10; // 10 seconds.
	for (var i = 0; i < points.length; ++i) {
		var eName = "TPoint" + (i + 1);
		var bmName = "bm"+(i+1);
		var pName = eName + "_anchor";
		var tName = "Ts" + (i + 1);
		var ts = tts[i];
		var d = left + Hms2Sec(ts) * 400 / 10;
		
		var vsbl = d > 390 ? "Collapsed" : "Visible";
		xaml += '<Ellipse Width="20" Height="20" Fill="#FF063DB5" Stroke="#FF000000" StrokeThickness="2" x:Name="'+eName+'" MouseLeftButtonDown="TimeUserLeftDown" MouseLeftButtonUp="TimeUserLeftUp" MouseMove="TimeUserMove" Canvas.Left="'+d+'" Canvas.Top="0" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Visibility="'+vsbl+'"/>';
		
		
		var stub = '<Ellipse Width="10" Height="10" Fill="#FF063DB5" Stroke="#FF000000" StrokeThickness="1" x:Name="'+bmName+'" MouseLeftButtonUp="cit" Canvas.Left="'+(400*i/points.length)+'" Canvas.Top="35" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"/>';
		var a = Plugin.content.createFromXaml(stub);
		if (i == 0) stubs.children.clear();
		stubs.children.add(a);
		
		
		xaml += '<Path Width="1" Height="120" Fill="#FF063DB5" Stretch="Fill" Stroke="#FF5BE5F9" StrokeThickness="1" Data="M8,40 L8,240" x:Name="'+pName+'" Canvas.Left="'+(d + 10)+'" Canvas.Top="20" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Visibility="'+vsbl+'"/>';
		
		var top = -10;
		if (i % 2 == 0) top = 20;
		xaml += '<TextBlock Width="60" Height="12" TextWrapping="Wrap" Text="'+ts+'" FontSize="8" FontFamily="Lucida Sans Unicode" x:Name="'+tName+'" Canvas.Left="'+(d - 10)+'" Canvas.Top="'+top+'" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Visibility="'+vsbl+'"/>';
		
		//left += 40;
	}
	
	xaml += '<TextBlock Width="10" Height="10" Canvas.Left="400" Canvas.Top="0" Text="txt';
	xaml += pn;
	xaml += '" TextWrapping="Wrap" FontSize="8" FontFamily="Arial" Visibility="Collapsed" x:Name="PN" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"/></Canvas>';
	
	var obj = Plugin.content.createFromXaml(xaml);
	slots.children.add(obj);
	slots.addEventListener("MouseLeftButtonDown", OnSlotsLBD);
	slots.addEventListener("MouseLeftButtonUp", OnSlotsLBU);
	slots.addEventListener("MouseMove", OnSlotsMM);
	
	for (var i = 0; i < points.length; ++i) {
		Plugin.content.findName("TPoint" + (i + 1)).Fill.color = points[i].Fill.color;
		Plugin.content.findName("bm" + (i + 1)).Fill.color = points[i].Fill.color;
	}
	
	// Init Clock
	var crt = Plugin.content.findName("crt");
	crt["Angle"]=0;
}

function Sec2Hms(secs) {
	var h = 0;
	var m = 0;
	var s = 0;
	if (secs < 60)
		s = secs;
	else {
		//s = secs % 60;
		s = Math.round(parseFloat(secs % 60)*1000)/1000;
		var min = parseInt(secs / 60);
		
		if (min >= 60) {
			m = min % 60;
			h = parseInt(min / 60);
		} else
			m = min;
	}
	
	return h + ":" + m + ":" + s;
}

function Hms2Sec(hms) {
	var a = hms.split(":");
	return parseFloat(a[0]) * 3600 + parseFloat(a[1]) * 60 + parseFloat(a[2]);
}

function GetSpot(Plugin, left, top, name) {
	var xaml = '<Ellipse xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" ';
	if (name != null)
		xaml += 'x:Name="'+name+'" ';
	else {
		xaml += 'x:Name="spot'+spotIdx+'"';
		spotIdx++;
	}
	clrIdx = clrIdx % colors.length;
	xaml += ' Width="8" Height="8" Fill="'+colors[clrIdx++]+'" Canvas.Left="'+left+'" Canvas.Top="'+top+'" Canvas.ZIndex="1" Stroke="#FFA2E1F4" StrokeThickness="1" MouseLeftButtonDown="spotLMD" MouseLeftButtonUp="spotLMU" MouseMove="spotMoving" MouseEnter="spotEnter" MouseLeave="spotLeave"/>';
	return Plugin.content.createFromXaml(xaml);
}

/*
 *<Canvas Width="30" Height="40" Canvas.Left="443" Canvas.Top="142.333" x:Name="User1" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
		<Ellipse Fill="#FFFFFFFF" Stroke="#FF000000" Width="8" Height="8" Canvas.Left="11" Canvas.Top="0" StrokeThickness="0.5"/>
		<Rectangle Fill="#FFFFFFFF" Stroke="#FF000000" StrokeThickness="0.5" Width="14" Height="24" Canvas.Left="8" Canvas.Top="8"/>
		<Rectangle Fill="#FFFFFFFF" Stroke="#FF000000" StrokeThickness="0.5" Width="6" Height="15" Canvas.Top="8" Canvas.Left="2"/>
		<Rectangle Fill="#FFFFFFFF" Stroke="#FF000000" StrokeThickness="0.5" Width="6" Height="8" Canvas.Top="32" Canvas.Left="8"/>
		<Rectangle Fill="#FFFFFFFF" Stroke="#FF000000" StrokeThickness="0.5" Width="6" Height="15" Canvas.Left="22" Canvas.Top="8"/>
		<Rectangle Fill="#FFFFFFFF" Stroke="#FF000000" StrokeThickness="0.5" Width="6" Height="8" Canvas.Left="16" Canvas.Top="32"/>
		<TextBlock Width="10.792" Height="11" Text="11" TextWrapping="Wrap" FontSize="8" Canvas.Top="13.375" Canvas.Left="9.59" FontWeight="Bold" Foreground="#FFFF0000" FontStretch="Normal"/>
	</Canvas>
 */
function GetPlayer(Plugin, name, num, trigger) {
	var t = trigger;
	if (trigger == null) t = '';
	var xaml = '<Canvas Width="30" Height="40" Canvas.Left="0" Canvas.Top="0" x:Name="'+name+'" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" MouseLeftButtonDown="userLeftDown">'+t+'<Ellipse Fill="#FFFFFFFF" Stroke="#FF000000" Width="8" Height="8" Canvas.Left="11" Canvas.Top="0" StrokeThickness="0.5"/><Rectangle Fill="#FFFFFFFF" Stroke="#FF000000" StrokeThickness="0.5" Width="14" Height="24" Canvas.Left="8" Canvas.Top="8"/><Rectangle Fill="#FFFFFFFF" Stroke="#FF000000" StrokeThickness="0.5" Width="6" Height="15" Canvas.Top="8" Canvas.Left="2"/><Rectangle Fill="#FFFFFFFF" Stroke="#FF000000" StrokeThickness="0.5" Width="6" Height="8" Canvas.Top="32" Canvas.Left="8"/><Rectangle Fill="#FFFFFFFF" Stroke="#FF000000" StrokeThickness="0.5" Width="6" Height="15" Canvas.Left="22" Canvas.Top="8"/><Rectangle Fill="#FFFFFFFF" Stroke="#FF000000" StrokeThickness="0.5" Width="6" Height="8" Canvas.Left="16" Canvas.Top="32"/></Canvas>';
	
	var user = Plugin.content.createFromXaml(xaml);
	var xaml = '<TextBlock Width="10.792" Height="11" Text="'+num+'" TextWrapping="Wrap" FontSize="8" Canvas.Top="13" Canvas.Left="0" FontWeight="Bold" Foreground="#FFFF0000" FontStretch="Normal"/>';
	var tb = Plugin.content.createFromXaml(xaml);
	tb["Width"] = tb.actualWidth;
	tb["Canvas.Left"] = (30 - tb.width) / 2;
	user.children.add(tb);
	
	return user;
}

function gn(u) {
	var c = u.children;
	var n = c.getItem(c.count - 1);
	return n["Text"];
}

slideo.Page = function() 
{
}

slideo.Page.prototype =
{
	handleLoad: function(control, userContext, rootElement) 
	{
		this.control = control;
		
		// Sample event hookup:	
		rootElement.addEventListener("MouseLeftButtonDown", Silverlight.createDelegate(this, this.handleMouseDown));
	},
	// Sample event handler
	handleMouseDown: function(sender, eventArgs) 
	{
		// The following line of code shows how to find an element by name and call a method on it.
		// this.control.content.findName("Storyboard1").Begin();
	}
}
function load(name) {
	var dl = GetPlugin().createObject("downloader");
	dl.addEventListener("completed", onLoadCompleted);
	dl.open("GET", "data/"+name+".xaml");
	dl.send();
}
function onLoadCompleted(sender, eventArgs) {
	var obj = sender.getHost().content.createFromXamlDownloader(sender, "");
	obj["Canvas.Left"]=21;
	obj["Canvas.Top"]=22.5;
	var root = sender.findName("Player");
	var a = sender.findName(obj["Name"]);
	if (a != null) a.getparent().children.remove(a);
    root.children.add(obj);
}
function onPlay(sender, eventArgs) {
	if (sender["Name"] == "PlayerPlay") {
		for (var i = 0; ; i++) {
			var story = sender.findName("GoalVideo" + i);
			if (story != null) {
				story.stop();
				story.Begin();
			} else
				break;
		}
	} else {
		for (key in Stories) {
			var story = sender.findName(Stories[key]);
			story.Stop();
			story.Begin();
		}
	}
}
function onPause(sender, eventArgs) {
	//var sb = sender.findName("GoalVideo");
	//sb.Pause();
	if (sender["Name"] == "PlayerPause") {
		for (var i = 0; ; i++) {
			var story = sender.findName("GoalVideo" + i);
			if (story != null)
				story.Pause();
			else
				break;
		}
	} else {
		for (key in Stories) {
			var story = sender.findName(Stories[key]);
			story.Pause();
		}
	}
}
function onResume(sender, eventArgs) {
	if (sender["Name"] == "PlayerResume") {
		for (var i = 0; ; i++) {
			var story = sender.findName("GoalVideo" + i);
			if (story != null)
				story.Resume();
			else
				break;
		}
	} else {
		for (key in Stories) {
			var story = sender.findName(Stories[key]);
			story.Resume();
		}
	}
}
function onStop(sender, eventArgs) {
	if (sender["Name"] == "PlayerStop") {
		for (var i = 0; ; i++) {
			var story = sender.findName("GoalVideo" + i);
			if (story != null)
				story.Stop();
			else
				break;
		}
	} else {
		for (key in Stories) {
			var story = sender.findName(Stories[key]);
			story.Stop();
		}
	}
}

function fieldLDown(sender, eventArgs) {
	//alert(sender["Name"]);
	//alert(objMoving["Name"]);
	var pos = eventArgs.getPosition(sender);
	if (mode == MODES["PATH"] && objMoving != null) {
		var name = objMoving["Name"];
		if (UStats[name] == SUBMODES["PATH_INIT"])
			UStats[name] = SUBMODES["PATH_SELECTED"];
		else {
			var left = pos.x - 4;
			var top = pos.y - 4;
			var spot = GetSpot(sender.getHost(), left, top, null);
			field.children.add(spot);
			
			/* Save the spot */
			var pathname = "path" + (pathIdx - 1);
			if (PPs[pathname] == null) PPs[pathname] = new Array();
			PPs[pathname].push(spot);
		}
		if (UStats[name] == SUBMODES["PATH_SELECTED"]) {
			var pl = sender.findName("path" + (pathIdx - 1));			
			Paths[pathIdx - 1] = updateEndPoint(pl, Paths[pathIdx - 1], pos, true);
		}
	}
}

function onDragDropMLDown(sender, eventArgs) {
	bDdrop = true;
	sender.captureMouse();
}

function onDragDropMLUp(sender, eventArgs) {
	bDdrop = false;
	sender.releaseMouseCapture();
}

function onDragDropMMove(sender, eventArgs) {
	if (bDdrop) {
		var pos = eventArgs.getPosition(null);
		var width = 30;
		var height = 30;
		var left = pos.X - width / 2 - 40;
		var top = pos.Y - height / 2 - 5;
		sender["Canvas.Left"] = left;
		sender["Canvas.Top"] = top;
		//obj.Left = left;
		//obj.Top = top;
	}
}

/* Time Editor Mouse Event Listener */
function OnSlotsLBD(sender, eventArgs) {
	
	if (!bTimeMoving) {
		sender.captureMouse();
		bTsMoving = true;
		tsCurPos = eventArgs.getPosition(sender.findName("Slots"));
		sender["Cursor"] = "Hand";
	}
}
function OnSlotsLBU(sender, eventArgs) {
	if (!bTimeMoving) {
		sender.releaseMouseCapture();
		bTsMoving = false;
		tsCurPos = null;
		sender["Cursor"] = "Default";
	}
}
function OnSlotsMM(sender, eventArgs) {
	if (bTsMoving && !bTimeMoving) {
		var pos = eventArgs.getPosition(sender.findName("Slots"));
		var delta = pos.x-tsCurPos.x;
		var crt = sender.findName("crt");
		if (tbm(sender.getHost(), delta)) {			
			crt["Angle"]=crt["Angle"]+(d2a(-delta));
		} else {
			// Move back to X:0
			var left = sender.findName("TSpots")["Canvas.Left"];
			tbm(sender.getHost(), -left);
			crt["Angle"]=crt["Angle"]+(d2a(-left));
		}
		tsCurPos = pos;
	}
}

function cit(sender, eventArgs) {
	var name = sender["Name"];
	var name = "TPoint"+name.substring(2);
	var tgt = sender.findName(name);
	var crt = sender.findName("crt");
	var ts = sender.findName("TSpots");
	var delta = 190 - tgt["Canvas.Left"] - ts["Canvas.Left"];
	if (190 - tgt["Canvas.Left"] > 0) delta = -ts["Canvas.Left"];
	GetPlugin();
	tbm(Plugin, delta);
	//crt["Angle"]=crt["Angle"]+(d2a(left));
}
/* update timer value */
function utv(Plugin) {
	var timer = Plugin.content.findName("timer");
	var tv = Plugin.content.findName("timer_val");
	var sec = (-Plugin.content.findName("TSpots")["Canvas.Left"] + 200)/40;
	tv.text = Sec2Hms(sec);
	tv.width = 200; // Tricky. The setting above will reset the width to about 30.
	tv["Width"]= tv["actualWidth"];
	tv["Canvas.Left"] = 200-tv.width/2;
}
/*distance to angle*/
function d2a(dist) {
	return dist/400;
}

/* Is TPoint? */
function istp(name) {
	if (name.substring(0,6)=="TPoint") {
		var id = name.substring(7);
		return !isNaN(id);
	}
}
/* Time Bar Movement */
function tbm(Plugin, dx) {
	document.getElementById("errorLocation").innerText=bPinning ? "Pinned" : "Not Pinned";
	var cs = Plugin.content.findName("Slots").children;
	var tspots = Plugin.content.findName("TSpots");
	var crt = Plugin.content.findName("crt");
	if (tspots["Canvas.Left"]>=0&&dx>0) return false;
	
	for (var i = 0; i < cs.count; i++) {
		var it = cs.getItem(i);
		var name = it["Name"];
		if (name != "sb" && name != "Mark" && name != "timer" && name != "timer_val") {
			it["Canvas.Left"] = it["Canvas.Left"] + dx;
				
			if (name != "TSpots") {
				if (it["Canvas.Left"] < 0) it["Canvas.Left"] = 400 + it["Canvas.Left"]%400;
				else if (it["Canvas.Left"] > 400) it["Canvas.Left"] = it["Canvas.Left"]%400;
			} else {
				var cn = it.children;
				for (var j = 0; j < cn.count - 1; j++) { // count - 1 is to shrug off the TextBlock
					var c = cn.getItem(j);
					if (PinSet[c["Name"]] == 1 && istp(c["Name"])) tum(Plugin, c["Name"], c["Canvas.Left"]+10-dx);
					//c["Canvas.Left"] = c["Canvas.Left"] - dx; // Move back.
					
					var cx = c["Canvas.Left"] + c["Width"]/2;
					var left = cx+it["Canvas.Left"];
					c["Visibility"] = (left < 0 || left > 390) ? "Collapsed" : "Visible";
					/*
					if (cx + it["Canvas.Left"] < 0)
						c["Visibility"] = "Collapsed";
					else
						c["Visibility"] = "Visible";
					*/
				}
			}
		}
	}
	utv(Plugin);
	return true;
}

/* Clock Mouse Event Listener */
function OnCLBD(sender, eventArgs) {
	bClockMoving = true;
	sender["Cursor"] = "Hand";
	sender.captureMouse();
}
function OnCLBU(sender, eventArgs) {
	bClockMoving = false;
	sender["Cursor"] = "Default";
	sender.releaseMouseCapture();
}
function OnCMM(sender, eventArgs) {
	if (bClockMoving) {
		var pos = eventArgs.getPosition(sender.findName("Clock"));
		var angle = cr(pos.x, pos.y);
		if (pos.x < 100 && pos.y < 60 && angle > 270)
			return;
		sender.findName("crt")["Angle"]=angle;
		// Synchronize the bar.
		var left = sender.findName("TSpots")["Canvas.Left"];
		GetPlugin();
		tbm(Plugin, (-400*angle-left));
		tsCurAng = angle;
	}
}
function dist(deltaAlpha) {
	return 400*deltaAlpha; // pixels
}
function cr(x, y) {
	var a = x - 100;
	var b = y - 60;
	var denominator = Math.sqrt(a*a + b*b);
	var sinsqr = (1 + b/denominator)/2;
	var sinalpha = Math.sqrt(sinsqr);
	var angle = Math.asin(sinalpha) * 2;
	var angle = angle * 180 / Math.PI;
	
	if (x <= 100) angle = 360-angle;
	if (angle == 360) angle = 0;
	return angle;
}


function onModeChange(sender, eventArgs) {
	pd(); // Complete the possible editing actions.
	// If user is being moved, mode change is not enabled.
	if (objMoving != null && UStats[objMoving["Name"]] == SUBMODES["USER_MOVING"])
		return;
		
	//if (submode != SUBMODES["USER_MOVING"]) {
		var modeName = sender["Name"];
		if (modeName == 'pick')
			mode = MODES["PICK"];
		else if (modeName == 'user')
			mode = MODES["USER"];
		else if (modeName == 'remove')
			mode = MODES["REMV"];
		else if (modeName == 'save')
			mode = MODES["SAVE"];
		else if (modeName == 'path')
			mode = MODES["PATH"];
		else if (modeName == 'time')
			mode = MODES["TIME"];
		else if (modeName == 'hidePath')
			mode = MODES["HIDE"];
			
		CompSelected(sender);
	//}
}

function userLeftDown(sender, eventArgs) {
	var sName = sender["Name"];
	if (UStats[sName] == null)
		UStats[sName] = SUBMODES["USER_INIT"];
	
	if (mode != MODES["USER"] && mode != MODES["PATH"] && mode != MODES["PICK"] && mode != MODES["REMV"])
		return;
	
	GetPlugin();
	//var Plugin = sender.getHost();	
	if (mode == MODES["USER"]) {
		if (UStats[sName] == SUBMODES["USER_MOVING"]) {
			UStats[sName] =  SUBMODES["USER_MOVED"];
			
			if (editor == null)
				editor = sender.findName("Editor");
			if (field == null) 
				field = sender.findName("Field");
			
			/*
			editor.children.remove(sender);
			if ( !field.children.remove(sender) ) { 
			 //Tricky. If this deleted element is the child of the parent, true is returned; otherwise, false is returned.
				
				// Adjust the coordinates. The sender is on the Editor canvas now.
				sender["Canvas.Left"] = sender["Canvas.Left"] - 40;
				sender["Canvas.Top"] = sender["Canvas.Top"] - 5;
			}
			field.children.add(sender);
			*/
			
			objMoving = null;
		} else if (UStats[sName] == SUBMODES["USER_MOVED"]) {
			UStats[sName] = SUBMODES["USER_SELECTED"];
			objMoving = sender;
		} else if (UStats[sName] == SUBMODES["USER_INIT"]) {
			UStats[sName] =  SUBMODES["USER_SELECTED"];
			/* Save the original position */
			initX = sender["Canvas.Left"];
			initY = sender["Canvas.Top"];
			objMoving = sender;
			
			if (users == null)
				users = sender.findName("Users");
			if (editor == null) 
				field = sender.findName("Field");
			
			users.children.remove(sender);
			
			/* Adjust the coordinates. The sender is on the Users canvas now. */
			sender["Canvas.Left"] = sender["Canvas.Left"] + 360;
			sender["Canvas.Top"] = sender["Canvas.Top"] + 5;
			field.children.add(sender);
			UinF.push(sender);
			
			/* Add event listener */
			sender.addEventListener("MouseMove", userMouseMove);
			sender.addEventListener("MouseLeftButtonUp", userLeftUp);
		}
		//sender["StrokeThickness"] = ((UStats[sName] == SUBMODES["USER_SELECTED"]) ? 2 : 1);
	} else if (mode == MODES["PATH"]){
		var points = PPs[PUs[sName]];
		//alert(UStats[sName]);
		if (UStats[sName] == SUBMODES["PATH_INIT"]) {
			if (field == null)
				field = sender.findName("Field");
			
			var name = "path" + pathIdx;
			
			if (!UserHasPath(PUs, sName) && objMoving == null) {
				objMoving = sender;
				
				var x = sender["Canvas.Left"] + sender["Width"] / 2;
				var y = sender["Canvas.Top"] + sender["Height"] / 2;
				
				
				var xaml = '<Polyline x:Name="' + name + '" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Points="' + x + ',' + y + '" Stroke="#FFC4DFF9" StrokeThickness="4" Canvas.Left="0" Canvas.Top="0" Canvas.ZIndex="1" Opacity="0.4"/>';
				var path = Plugin.content.createFromXaml(xaml);
				path.addEventListener("MouseLeftButtonDown", pathSelected);
				//path.addEventListener("MouseOver", pathEnter);
				//path.addEventListener("MouseOut", pathOut);
				field.children.add(path);
				
				/* Save the points in each path. */
				Paths[pathIdx] = x + ',' + y;
				PUs[name] = sender["Name"]; // PathName->UserName map.
				pathIdx++;
				
				/* At the PATH_INIT, the spot is drawed by the user handler. Later it will be drawed by field handler. */
				var left = sender["Canvas.Left"] + sender["Width"]/2 - 4;
				var top = sender["Canvas.Top"] + sender["Height"]/2 - 4;
				var spot = GetSpot(Plugin, left, top, null);
				field.children.add(spot);
				
				/* Save the spot */
				if (PPs[name] == null) PPs[name] = new Array();
				PPs[name].push(spot);
				
			}
		}
		//sender["StrokeThickness"] = ((UStats[sName] == SUBMODES["PATH_SELECTED"]) ? 2 : 1);
	} else if (mode == MODES["PICK"]) {
		//sender["StrokeThickness"] = sender["StrokeThickness"] + 1;
		sender.cursor = "Hand";
		sender.captureMouse();
		bUserMoving = true;
	} else if (mode == MODES["REMV"]) {
		sender.triggers.clear(); // Clear the animation
		ruff(sender);
	}
}

/* Remove user from field */
function ruff(u) {
	for (k in PUs) if (PUs[k] == u["Name"]) return;
	field.children.remove(u);
	u["Canvas.Left"] = Math.random() * 30;//60-30
	u["Canvas.Top"] = Math.random() * 360;//400-40
	users.children.add(u);
	UStats[u["Name"]] = SUBMODES["USER_INIT"];
	for (var i = 0; i < UinF.length; i++) {
		if (UinF[i]["Name"] == u["Name"]) {
			UinF.splice(i, 1);
			break;
		}
	}
}

function userMouseMove(sender, eventArgs) {
	if (bUserMoving && (mode == MODES["PICK"])) {
		var pos = eventArgs.getPosition(field);
		
		var left = - sender["Width"]/2;
		if (pos.x > 0 && pos.x < field["Width"])
			left = pos.x + left;
		else if (pos.x >= field["Width"])
			left = field["Width"] + left;
		
		var top = - sender["Height"]/2;
		if (pos.y > 0 && pos.y < field["Height"])
			top = pos.y + top;
		else if (pos.y >= field["Height"])
			top = field["Height"] + top;
		sender["Canvas.Left"] = left;sender["Canvas.Top"] = top;
	}
}

function userLeftUp(sender, eventArgs) {
	if (mode == MODES["PICK"]) {
		sender.cursor = "Default";
		sender.ReleaseMouseCapture();
		bUserMoving = false;
	}
}

/* The editor canvas is listening the MouseMove event. */
function userMoving(sender, eventArgs) {
	if (mode == MODES["USER"] && objMoving != null) {
		//alert(mode + ";" + submode);
		var sName = objMoving["Name"];
		if (UStats[sName] == SUBMODES["USER_SELECTED"]) {
			UStats[sName] = SUBMODES["USER_MOVING"];
		}
		if (UStats[sName] == SUBMODES["USER_MOVING"]) {
			var pos = eventArgs.getPosition(field);
			if (sName == "Ball") {
				var left = pos.X - 4;
				var top = pos.Y - 4;
			} else {
				var left = pos.x - 12;
				var top = pos.y - 15;
			}
			objMoving["Canvas.Left"] = left;
			objMoving["Canvas.Top"] = top;
		}
	}
}	

/* The field is listening for the path editing operation. */
function fieldMoving(sender, eventArgs) {
	//alert(objMoving["Name"]);
	//alert(UStats[objMoving["Name"]]);
	if (mode == MODES["PATH"] && objMoving != null) {
		var name = objMoving["Name"];
		if (UStats[name] == SUBMODES["PATH_SELECTED"]) {
			var field = sender.findName("Field");
			var pl = sender.findName("path" + (pathIdx - 1));
			var pos = eventArgs.getPosition(field);
			
			var points = Paths[pathIdx - 1];
			Paths[pathIdx - 1] = updateEndPoint(pl, points, pos, false);
		}
	}
}

function TimeUserLeftDown(sender, eventArgs) {
	GetPlugin();
	if (bPinning) pin(sender["Name"], Plugin);
	sender.captureMouse();
	sender["StrokeThickness"] = sender["StrokeThickness"] + 1;
	bTimeMoving = true;
}
function TimeUserLeftUp(sender, eventArgs) {
	sender.ReleaseMouseCapture();
	sender["StrokeThickness"] = sender["StrokeThickness"] - 1;
	bTimeMoving = false;
}
function TimeUserMove(sender, eventArgs) {
	if (bTimeMoving) {
		GetPlugin();
		unpin(sender["Name"], Plugin);
		var time = sender.findName("TSpots")
		var pos = eventArgs.getPosition(time);		
		tum(Plugin, sender["Name"], pos.x);
	}
}

function tum(Plugin, un, to) {
	var sender = Plugin.content.findName(un);
	var time = Plugin.content.findName("TSpots");
	var name = sender["Name"];
	var id = name.substring(6);
	var anchor = Plugin.content.findName(sender["Name"] + "_anchor");
	var ts = Plugin.content.findName("Ts" + id);
	//document.getElementById("errorLocation").innerText = name + ";" + sender["Name"] + "_anchor" + ";" + "Ts" + id;
	var pre = Plugin.content.findName("TPoint" + (parseInt(id) - 1));
	var post = Plugin.content.findName("TPoint" + (parseInt(id) + 1));
	var min = -10;
	//var max = parseInt(time["Width"]);
	var max = 288000;
	var hw = sender["Width"] / 2;
	
	if (pre != null) min = pre["Canvas.Left"];
	if (post != null) max = post["Canvas.Left"] + hw;
	
	if ( to >= max)
		sender["Canvas.Left"] = max - hw;
	else {
		if ( (to - hw) <= min)
			sender["Canvas.Left"] = min;
		else
			sender["Canvas.Left"] = to - hw;
	}
	anchor["Canvas.Left"] = sender["Canvas.Left"] + hw;
	ts["Canvas.Left"] = anchor["Canvas.Left"] - ts.actualwidth / 2;
		
	ts["Text"] = Sec2Hms(10 * timeUnit * parseInt(anchor["Canvas.Left"]) / time["Width"]);
	var txtObj = Plugin.content.findName("PN");
	var pathname = txtObj["Text"].substring(3);
	var tss = PTs[pathname];
	tss[id - 1] = ts["Text"];
}

function onKeyUp(sender, keyEventArgs) {
	
	if (keyEventArgs.key == 8) {
		pd();
		/*
		if (mode == MODES["PATH"] && objMoving != null) {
			var name = objMoving["Name"];
			if (UStats[name] == SUBMODES["PATH_SELECTED"]) {
				UStats[name] = SUBMODES["PATH_DONE"];
				
				var pathname = "path" + (pathIdx - 1);
				var pl = sender.findName(pathname);
				var points = Paths[pathIdx - 1];
				
				var idx = points.lastIndexOf(" ");
				if (idx == -1)
					idx = points.length;
				var np = points.substring(0, idx);
				Paths[pathIdx - 1] = np;
				pl["Points"] = np;
				
				objMoving = null;
				
				PTs[pathname] = new Array();
				var cnt = Paths[pathIdx - 1].split(" ").length;
				for (i = 0; i < cnt; ++i) {
					var ts = "00:00:0" + i;
					PTs[pathname].push(ts);
				}
			}			
		}
		*/
	}
}
/* path editing done */
function pd() {
	if (mode == MODES["PATH"] && objMoving != null) {
		var name = objMoving["Name"];
		if (UStats[name] == SUBMODES["PATH_SELECTED"]) {
			UStats[name] = SUBMODES["PATH_DONE"];
					
			var pathname = "path" + (pathIdx - 1);
			var pl = GetPlugin().content.findName(pathname);
			var points = Paths[pathIdx - 1];
					
			var idx = points.lastIndexOf(" ");
			if (idx == -1)
				idx = points.length;
			var np = points.substring(0, idx);
			Paths[pathIdx - 1] = np;
			pl["Points"] = np;
				
			objMoving = null;
			
			PTs[pathname] = new Array();
			var cnt = Paths[pathIdx - 1].split(" ").length;
			for (i = 0; i < cnt; ++i) {
				var ts = "00:00:0" + i;
				PTs[pathname].push(ts);
			}
		}
	}
}
function pathSelected(sender, eventArgs) {
	if (mode == MODES["REMV"]) {
		var name = sender["Name"];
		var ps = PPs[name];
		if (ps.length == 1) return; // Avoid the tricky.
		
		field.children.remove(sender);
		
		var tmpPaths = new Array();
		for (key in Paths) {
			if (key != name)
				tmpPaths[key] = Paths[key];
		}
		Paths = tmpPaths;
		
		var tmpPUs = new Array();
		for (key in PUs) {
			if (key != name) tmpPUs[key] = PUs[key];
			else UStats[PUs[key]] = SUBMODES["PATH_INIT"];
		}
		PUs = tmpPUs;
		
		var tmpPTs = new Array();
		for (key in PTs) {
			if (key != name)
				tmpPTs[key] = PTs[key];
		}
		PTs = tmpPTs;
		
		
		for (key in ps) field.children.remove(ps[key]);
	} else if (mode == MODES["TIME"]) {
		for (var k in Paths) {
			var path = sender.findName("path" + k);
			if (path == null) continue;
			path["Opacity"] = (("path" + k) == sender["Name"] ? 0.8 : 0.4);
		}
		GetPlugin();
		bTE(Plugin, sender["Name"]);
		pathnamesel = sender["Name"];
	}
}

/*
 * function spotLeftMouseDown
 */
function spotLMD(sender, eventArgs) {
	if (mode == MODES["REMV"]) {
		// Update points in the line.
		for (key in PPs) {
			var points = PPs[key];
			for (i = 0; i < points.length; ++i) {
				if (points[i]["Name"] == sender["Name"] && (i != 0 || points.length == 1)) {
					points.splice(i, 1);
					// Find the path
					var p = sender.findName(key);
					var id = key.substring(4);
					var ps = Paths[id];
					ps = ps.split(" ");
					ps.splice(i, 1);
					ps = ps.join(" ");
					Paths[id] = ps;
					p["Points"] = ps;
					/* remove from field */
					field.children.remove(sender);
					break;
				}
			}
		}
	} else if (mode == MODES["PATH"]) {
		for (key in PPs) {
			var points = PPs[key];
			if (points[points.length-1]["Name"] == sender["Name"]) {
				//if ((i + 1) == points.length) submode = SUBMODES["PATH_SELECTED"];
				objMoving = sender.findName(PUs[key]);
				UStats[objMoving["Name"]] = SUBMODES["PATH_INIT"];
				break;
			}
		}
		//if (ilp(sender)) objMoving = sender.findName(PUs[key]);
	} else {
		bSpotMoving = true;
		sender["StrokeThickness"] = sender["StrokeThickness"] + 1;
		sender.captureMouse();
	}
}
/* is last point */
function ilp(sender) {
	for (key in PPs) {
		var points = PPs[key];
		if (points[points.length-1]["Name"] == sender["Name"]) {
			return true;
		}
	}
	return false;
}
function spotEnter(sender, eventArgs) {
	if (mode == MODES["REMV"]) {
		sender["Canvas.Left"] = sender["Canvas.Left"] - sender["Width"] / 2;
		sender["Width"] = sender["Width"] * 2;
		sender["Canvas.Top"] = sender["Canvas.Top"] - sender["Height"] / 2;
		sender["Height"] = sender["Height"] * 2;
	} else if (mode == MODES["PATH"]) {
		if(ilp(sender)) sender["Cursor"] = "Hand";
	}
}
function spotLeave(sender, eventArgs) {
	if (mode == MODES["REMV"]) {
		sender["Width"] = sender["Width"] / 2;
		sender["Canvas.Left"] = sender["Canvas.Left"] + sender["Width"] / 2;
		sender["Height"] = sender["Height"] / 2;
		sender["Canvas.Top"] = sender["Canvas.Top"] + sender["Height"] / 2;
	} else if (mode == MODES["PATH"])
		sender["Cursor"] = "Default";
}
function spotMoving(sender, eventArgs) {
	if (bSpotMoving) {
		var pos = eventArgs.getPosition(field);
		
		var left = - sender["Width"]/2;
		if (pos.x > 0 && pos.x < field["Width"])
			left = pos.x + left;
		else if (pos.x >= field["Width"])
			left = field["Width"] + left;
		
		var top = - sender["Height"]/2;
		if (pos.y > 0 && pos.y < field["Height"])
			top = pos.y + top;
		else if (pos.y >= field["Height"])
			top = field["Height"] + top;
		
		// Update points in the line.
		for (key in PPs) {
			var points = PPs[key];
			for (i = 0; i < points.length; ++i) {
				if (points[i]["Name"] == sender["Name"]) {
					// Find the path
					var p = sender.findName(key);
					var id = key.substring(4);
					var ps = Paths[id];
					ps = ps.split(" ");
					
					var x = left + sender["Width"]/2;
					var y = top + sender["Height"]/2;
					ps[i] = x + "," + y;
					ps = ps.join(" ");
					Paths[id] = ps;
					p["Points"] = ps;
					
					// Update spot's location
					sender["Canvas.Left"] = left;sender["Canvas.Top"] = top;
				
					if (i == 0) {
						var un = PUs[key]; // user name
						var uo = sender.findName(un);
						uo["Canvas.Left"] = left + sender["Width"]/2 - uo["Width"]/2;
						uo["Canvas.Top"] = top + sender["Height"]/2 - uo["Height"]/2;
					}
					break;
				}
			}
		}
	}
}
/*
 * function spotLeftMouseUp
 */
function spotLMU(sender, eventArgs) {
	if (mode == MODES["REMV"]) {}
	else if (mode == MODES["PATH"]) {}
	else {
		bSpotMoving = false;
		sender["StrokeThickness"] = sender["StrokeThickness"] - 1;
		sender.ReleaseMouseCapture();
	}
}

function updateEndPoint(polyline, points, position, append) {
	if (append) {
		var new_points = points + " " + position.X + "," + position.Y;
		polyline["Points"] = new_points;
		return new_points;
	} else {
		var idx = points.lastIndexOf(" ");
		if (idx == -1)
			idx = points.length;
		var new_points = points.substring(0, idx) + " " + position.X + "," + position.Y;
		polyline["Points"] = new_points;
		return new_points;
	}
}

function ShowTips(sender, eventArgs) {
	var tips = sender.findName("Tips");
	var tbObj = sender.findName("Toolbar");
	var pos = eventArgs.getPosition(tbObj);
	
	tips.visibility = "Visible";
	var n = sender["Name"];
	if (n == "pick") {
		tips["Text"] = "Pick";
		tips["Canvas.Top"] = 5;
	} else if (n == "user") {
		tips["Text"] = "Player";
		tips["Canvas.Top"] = 50;
	} else if (n == "path") {
		tips["Text"] = "Edit Track";
		tips["Canvas.Top"] = 95;
	} else if (n == "remove") {
		tips["Text"] = "Delete";
		tips["Canvas.Top"] = 140;
	} else if (n == "time") {
		tips["Text"] = "Edit Time Ellapsed";
		tips["Canvas.Top"] = 185;
	} else if (n == "animate") {
		tips["Text"] = "Build Animation";
		tips["Canvas.Top"] = 230;
	} else if (n == "save") {
		tips["Text"] = "Save";
		tips["Canvas.Top"] = 275;
	} else if (n == "hidePath") {
		tips["Text"] = "Show/Hide Track";
		tips["Canvas.Top"] = 320;
	}
}

function HideTips(sender, eventArgs) {
	sender.findName("Tips").visibility = "Collapsed";
}

/* 
 * un=user1,user2,user3
 * no=10,11,12
 * nl=100,100,100 (number's left)
 * nt=100,100,100 (number's top)
 * nw=100,100,100 (number's width)
 * nh=100,100,100 (number's height)
 * ult=(100,100)-(100,200)-(100,300)
 * pn=path1,,path3
 * pp=(100,200 100,300 300,400)-(100,200 200,100)         -- Canvas.Left,Canvas.Top
 * pt=(00:00:00,00:00:01,00:00:02)-(00:00:00,00:00:02)
 * pf=(09fd,fdifdif,fff)_(ff,ff)
 */
function Commit(downloader) {
	var s_name = document.getElementById("slideoName").value;
	var Plugin = GetPlugin();
	if (Trim(s_name) == '') {
		alert("请输入您的Slideo的名称");
		return;
	}
	
	// 1. PUs
	var up = new Array();
	for (k in PUs) {
		if (PUs[k] != null)
			up[PUs[k]] = k;
	}
	
	// 2. UinF
	var un = "";
	var ult = "";
	var pn = "";
	var pp = "";
	var pt = "";
	var pf = "";
	var no = "";
	var nl = "";
	var nt = "";
	var nw = "";
	var nh = "";
	for (var i = 0; i < UinF.length; i++) {
		var tmp = UinF[i];
		var uname = tmp["Name"];
		un += uname;
		var uObj = Plugin.content.findName(uname);
		//var children = uObj.children;
		if (uname != "Ball") {
			var children = uObj.children;
			no += uObj.children.getItem(children.count - 1)["Text"];
			nl += uObj.children.getItem(children.count - 1)["Canvas.Left"];
			nt += uObj.children.getItem(children.count - 1)["Canvas.Top"];
			nw += uObj.children.getItem(children.count - 1)["Width"];
			nh += uObj.children.getItem(children.count - 1)["Height"];
		} else {
			no += "ball";
			nl += uObj["Canvas.Left"];
			nt += uObj["Canvas.Top"];
			nw += uObj["Width"];
			nh += uObj["Height"];
		}
		
		ult += "(" + tmp["Canvas.Left"] + "," + tmp["Canvas.Top"] + ")";
		
		var pathname;
		var point;
		var ptime;
		var pfill;
		if (up[uname] != null) {
			pathname = up[uname];
			var points = PPs[pathname];
			
			point = "(";
			pfill = "(";
			for (var j = 0; j < points.length; j++) {
				var p = points[j];
				
				point += p["Canvas.Left"] + "," + p["Canvas.Top"];
				pfill += p.Fill.color;
				if (j != (points.length - 1)) {
					point += " ";
					pfill += ",";
				}
			}
			point += ")";
			pfill += ")";
			
			var pts = PTs[pathname];
			ptime = "(";
			for (var k = 0; k < pts.length; k++) {
				ptime += pts[k];
				if (k != (pts.length - 1))
					ptime += ",";
			}
			ptime += ")";
		} else {
			pathname = "";
			point = "()";
			ptime = "()";
			pfill = "()";
		}
		pn += pathname;
		pp += point;
		pt += ptime;
		pf += pfill;
		if (i != (UinF.length - 1)) { un += ","; no += ","; nl += ",";nt += ",";nw += ",";nh += ",";ult += "-"; pn += ","; pp += "-"; pt += "-"; pf += "_"}
	}
	
	if (un == "") {
		alert("没有什么好保存的。先编辑您自己的Slideo吧。");
		return;
	}
	
	var params = "un="+un+"&no="+no+"&nl="+nl+"&nt="+nt+"&nw="+nw+"&nh="+nh+"&ult="+ult+"&pn="+pn+"&pp="+pp+"&pt="+pt+"&pf="+pf+"&sn="+s_name;
	alert(params);
	downloader.addEventListener("completed", onCompleted);
	downloader.open("GET", "do.php?"+params);
    //downloader.open("GET", "data/test.xaml");
    // Execute the Downloader request.
    downloader.send();
}

function onCompleted(sender, eventArgs) {
	alert("上传成功");
}

function LTrim(str){
	var i;
	for(i=0;i < str.length - 1; i++) {
		if(str.charAt(i)!=" " && str.charAt(i) != " ") {
			break;
		}
	}
	str = str.substring(i,str.length);
	return str;
}

function RTrim(str){
	var i;
	for(i=str.length-1;i>=0;i--) {
		if(str.charAt(i)!=" "&&str.charAt(i)!=" ")
			break;
	}
	str = str.substring(0,i+1);
	return str;
}

function Trim(str){ 
	return LTrim(RTrim(str));
}

/* Validate Slideo Name */
function vsn(name) {
	var Plugin = document.getElementById("SilverlightControl");
	var d = Plugin.createObject("downloader");
	d.addEventListener("completed", showResult);
	d.open("GET", "vf.php?n="+name);
    // Execute the Downloader request.
    d.send();
}

function showResult(sender, eventArgs) {
	var r = sender.ResponseText;
	var note = document.getElementById("note");
	if (r == 0) {
		var name = document.getElementById("slideoName");
		note.innerText = "!名称("+name.value+")已存在";
		name.value = "";
	} else {
		note.innerText = "";
	}
}

/*function Show Paths(show) */
function sp(s) {
	var visible = s ? "Visible":"Collapsed";
	var Plugin = document.getElementById("SilverlightControl");
	
	for ( k in PUs) {
		var p = Plugin.content.findName(k);
		if (p != null) {
			p.visibility = visible;
			var ps = PPs[k];
			for (i in ps) ps[i].visibility = visible;
			//break;
		}
	}
}

function PBLBD(sender, eventArgs) {
	var len = sender.source.length;
	var src = sender.source.substring(0, len - 8);
	sender.source = src+"down.png";
	if (src == "play_") onPlay(sender,eventArgs);
	else if (src == "stop_") onStop(sender, eventArgs);
	else if (src == "resume_") onResume(sender, eventArgs);
	else if (src == "pause_") onPause(sender, eventArgs);
}
function PBLBU(sender, eventArgs) {
	var len = sender.source.length;
	var src = sender.source.substring(0, len - 8);
	sender.source = src+"over.png";
}
function PBME(sender, eventArgs) {
	var len = sender.source.length;
	var src = sender.source.substring(0, len - 4);
	sender.source = src+"over.png";
}
function PBML(sender, eventArgs) {
	var len = sender.source.length;
	var src = sender.source.substring(0, len - 8);
	sender.source = src+".png";
}